using System;
using System.Collections.Generic;
using System.Text;

namespace PW.Mini.SlepowronskiJ.Siec.Aktywacja
{
    /// <summary>
    /// funkcja aktywacji tangens hiperboliczny
    /// </summary>
    /// <remarks>
    /// Definicja tanh funkcji aktywacji tanh = sinh/cosh
    /// <code>
    ///       (e^(x) - e^(-x))/2     e^(2x) - 1      2
    /// f(x) = ----------------  = ------------ = ----------- - 1
    ///       (e^(x) + e^(-x))/2     e^(2x) + 1    (1+e(-2x))
    /// 
    ///           4 e^(2x)    
    /// f`(x) = ------------- = (1+f(x))*(1-f(x))
    ///         (e^(2x)+1)^2
    /// </code>     
    /// </remarks>

    [Serializable]
    class TanhFunkcjaAktywacji : IFunkcjaAktywacji
    {

        public TanhFunkcjaAktywacji()
            : base()
        {
            nazwa = "Tanh";
            rodzajPolarnosci = SKALOWANIE_BIPOLARNE;
        }

        /// <summary>
        /// Clone the object.
        /// </summary>
        /// <returns>The cloned object.</returns>
        public override object Clone()
        {
            return new TanhFunkcjaAktywacji();
        }

        /// <summary>
        /// <code>
        ///       (e^(x) - e^(-x))/2     e^(2x) - 1      2
        /// f(x) = ----------------  = ------------ = ----------- - 1
        ///       (e^(x) + e^(-x))/2     e^(2x) + 1    (1+e(-2x))
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f(x)</returns>
        public override double WartoscFunkcji(double x)
        {
            return (2 / (1 + Math.Exp(-2 * x)) - 1);
        }

        /// <summary>
        /// <code>
        ///           4 e^(2x)    
        /// f`(x) = ------------- = (1+f(x))*(1-f(x))
        ///         (e^(2x)+1)^2
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f'(x)</returns>
        public override double WartoscPochodnejFunkcji(double x)
        {
            double fx = WartoscFunkcji(x);
            return 1 - fx*fx;
        }

        /// <inheritdoc />
        public override double DerivativeFunction(double b, double fx)
        {
            return 1 - fx * fx;
        }

    }
}
